<template>
  <div class="customizeSearch customer-dialog">
    <el-dialog :close-on-click-modal="false" ref="dialog" :visible.sync="dialogModel" :title="title" @close="handleClose" :close-on-press-escape="true" custom-class="customer-search-dialog" width="50%">
      <div class="dialogbody">
        <el-form class="formbody" ref="customizeForm">
          <el-form-item :label="$t('public.menu')" key="kMenus">
            <el-select v-model="formdata.menu">
              <el-option v-for="item in menus" :label="item.label" :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>

          <el-form-item :label="$t('customer.CustomerSearch.name')" key="kName">
            <el-input v-model="formdata.kName" size="mini"></el-input>
          </el-form-item>
          <el-form-item :label="$t('customer.CustomerSearch.condition')">
            <el-form class="formcontent">
              <div v-for="(item, index) in chooseOptions" class="formitem" :key="item.value + index +'form'">

                <el-select v-model="chooseObject[item.label]" @change="labelChange(chooseObject[item.label],index)">
                  <el-option :label="item.label" :value="item.value"></el-option>
                  <el-option v-for="(li, index1) in notChooseOptions" v-if="li.value !== item.value" :label="li.label" :value="li.value" :key="index1 + 'name'">
                  </el-option>
                </el-select>

                <m7-select class="relative" v-if="item.inputType !== 'date'  && item.inputType !== 'time' && item.inputType !== 'datetime'" value="1" >
                  <m7-option value="1" :label="$t('public.equal')"></m7-option>
                </m7-select>
                <el-select class="relative"
                           v-if="item.inputType === 'date' || item.inputType === 'time' || item.inputType === 'datetime'"
                           v-model="formdata.query[item.value][item.timeindex].relate" >
                  <el-option :label="$t('public.moreThan')" value="JGd0"></el-option>
                  <el-option :label="$t('public.lessThan')" value="JGx0"></el-option>
                </el-select>
                <!--输入框-->
                <el-input class="width196" v-if="item.inputType === 'input'" v-model="formdata.query[item.value]" :key="item.value + 'input'"></el-input>
                <!--多行文本-->
                <el-input class="width196" v-if="item.inputType === 'textarea'" type="textarea" :rows="2" :key="item.value + 'textarea'"
                          v-model="formdata.query[item.value]" ></el-input>
                <!--一般下拉-->
                <el-select class="width196" v-if="item.inputType === 'select'" v-model="formdata.query[item.value]" :key="item.value + 'select'"
                           :placeholder="$t('public.pleasePick')" >
                  <el-option v-for="option in item.data" :label="option.label" :value="option.value">
                  </el-option>
                </el-select>
                <cascader
                class="width196"
                v-if="item.data && item.data.isDic"
                :optionsId="item.data.dicId"
                :initCascaderValue="formdata.query[item.value]"
                :formId="item.value"
                @change="handleCascader">

                </cascader>
                <!--省份下拉框-->
                <el-select class="width196" v-if="item.inputType === 'area'" v-model="formdata.query[item.value]" :key="item.value + 'select'"
                           :placeholder="$t('public.pleasePick')" >
                  <el-option v-for="option in provinces" :label="option.label" :value="option.value"></el-option>
                </el-select>
                <!--日期时间选择-->
                <el-date-picker
                  class="width196"
                  v-if="item.inputType === 'date' || item.inputType === 'time' || item.inputType === 'datetime'"
                  v-model="formdata.query[item.value][item.timeindex].value"
                  type="datetime"
                  :placeholder="$t('customer.CustomerSearch.pleaseChooseTime')" >
                </el-date-picker>

                <!--占位-->
                <span class="width196" v-if="item.inputType === 'checkbox' || item.inputType === 'radio' "></span>
                <!--增删条件图标-->
                <i v-if="index === 0" class="el-icon-plus el-icon--right cursorpointer colorgreen" @click="addOptions"></i>
                <i v-if="index !== 0" class="iconfont icon-zuixiaohua el-icon--right cursorpointer colorred"
                   @click="deleteOptions(item, index)"></i>
                <!--多选-->
                <div v-if="item.inputType === 'checkbox'">
                  <el-checkbox-group v-if="item.inputType === 'checkbox'" v-model="formdata.query[item.value]" >
                    <el-checkbox v-for="checkitem in item.data" :label="checkitem.value">{{checkitem.label}}</el-checkbox>
                  </el-checkbox-group>
                </div>
                <!--单选-->
                <div v-if="item.inputType === 'radio'">
                  <el-radio-group v-model="formdata.query[item.value]" >
                    <el-radio v-for="radioitem in item.data" :label="radioitem.value">
                      {{radioitem.label}}
                    </el-radio>
                  </el-radio-group>
                </div>
                <!--市级选择-->
                <div v-if="item.inputType === 'area'">
                  <!--<m7-select class="width196" :disabled="true" value="1"  :options="[{'label':'市','value':'1'}]">-->
                  <!--</m7-select>-->
                  <el-select value="1" disabled
                             :placeholder="$t('public.pleasePick')" >
                    <el-option :label="$t('customer.city')" value="1"></el-option>
                  </el-select>
                  <m7-select class="relative" value="1" :options="[{'label':$t('public.equal'),'value':'1'}]">
                  </m7-select>
                  <el-select class="width196" v-model="formdata.query.city"
                             :placeholder="$t('public.pleasePick')" >
                    <el-option v-for="option in cities" :label="option.label" :value="option.value"></el-option>
                  </el-select>
                  <!--<m7-select class="width196" v-model="formdata.query.city" :options="cities"></m7-select>-->
                </div>

              </div>
            </el-form>
          </el-form-item>
        </el-form>
        <div class="footer">
          <el-button @click.stop="cancel"  class="primary_btn">{{$t('public.cancel')}}</el-button>
          <el-button type="primary" @click.stop="saveSearch" class="primary_btn">{{$t('public.save')}}</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
  /*
  * 代码结构说明：
  * 1.主要功能，设置自定义搜索条件，所有条件选项为预设+客户自定义。不同类型。选中以后加入列表，下拉框中展示未选中项条件。
  * 2.设计说明：主要思路，通过数组v-for渲染，未选中项数组 = 所有条件数组 - 选中条件数组。
  *   条件增加或改变后，触发未选中数组计算，随后触发v-for重新渲染，保证下拉框中展示未选中项条件及时更新。特别的，时间条件可多选，需增设不同顺序标记比较计算。
  * 3.选中项条件以v-model形式，绑定在formdata.query 这一对象中，增删改条件触发对应set delete操作。
  * 4.剩余问题，条件选中较多时，页面输入卡顿，对比判断是由于页面el-select元素过多导致。引入自定义组件m7-select有改善，但由于无法解决下拉框悬浮显示问题，未选用。
  *
  * */
  // TODO：页面性能问题，m7Select悬浮显示
  import Vue from 'vue'
  import {deepClone, getFormatDateTime} from '@/utils/m7Utils'
//  import {checkform} from '@/utils/validate'
  import {sortCustomFields} from '@/utils/customerUtils.js'
  import m7Select from '@/components/public-modules/m7-select/m7-select.vue'
  import Cascader from '@/components/public-modules/cache/Cascader'
  import m7Option from '@/components/public-modules/m7-select/m7-option.vue'
  export default {
    name: 'CustomizeSearchDialog',
    data () {
      return {
        dialogModel: false,
        title: '',
        searchOptions: [],
        chooseOptions: [],
        inputrelate: '',
        modifystatus: false,
        CustomizeId: '',
        formdata: {
          menu: 'customer_my',
          kName: '',
          query: {}
        },
        menus: [
          {
            label: this.$t('customer.customerMy'),
            value: 'customer_my'
          }, {
            label: this.$t('customer.customerPlan'),
            value: 'customer_plan'
          }, {
            label: this.$t('customer.customerAll'),
            value: 'customer_all'
          }
        ],
        provinceCache: {options: []},
        provinces: [],
        chooseObject: {},
        propsitem: {}
      }
    },
    components: {
      m7Select,
      m7Option,
      Cascader
    },
    watch: {
      cities (curr, prev) {
        if (curr.length > 1 && prev.length > 1) {
          if (curr[1].value !== prev[1].value) {
            this.formdata.query.city = ''
          }
        }
      },
      chooseOptions () {
        this.chooseObject = {}
        this.chooseOptions.forEach((item) => {
          if (this.chooseObject[item.label] === undefined) {
            Vue.set(this.chooseObject, item.label, item.value)
          }
        })
      }
    },
    methods: {
      handleCascader (val) {
        this.formdata.query[val.id] = val.val
      },
      showCache (item) {
        let vm = this
        this.formdata.query = {}
        this.chooseOptions = []
        let searchOptions = deepClone(this.searchOptions)
        if (this.isEmptyObject(item.query)) {
          let choose = deepClone(this.searchOptions)[0]
          this.chooseOptions.push(choose)
          Vue.set(this.formdata.query, choose.value, '')
        }
        for (let key in item.query) {
          if (key === 'city') {
            Vue.set(this.formdata.query, key, item.query[key])
          }
          searchOptions.forEach((option) => {
            if (option.value === key) {
              if (option.inputType === 'date' || option.inputType === 'time' || option.inputType === 'datetime') {
                if (!vm.formdata.query[option.value]) {
                  Vue.set(vm.formdata.query, option.value, {})
                }
                let timekeys = Object.keys(item.query[key])
                timekeys.forEach((timeitem, index) => {
                  if ((index + 1) === option.timeindex) {
                    Vue.set(vm.formdata.query[option.value], index + 1, {
                      relate: timeitem,
                      value: new Date(item.query[key][timeitem])
                    })
                    vm.chooseOptions.push(option)
                  }
                })
              } else {
                Vue.set(vm.formdata.query, option.value, item.query[key])
                vm.chooseOptions.push(option)
              }
            }
          })
        }
      },
      isEmptyObject (obj) {
        for (let key in obj) {
          return false
        }
        return true
      },
      open (item) {
        let vm = this
        this.dialogModel = true
        this.title = this.$t('customer.CustomerSearch.addCustomizeSearch')
        if (item) {
          this.propsitem = deepClone(item)
          this.title = this.$t('customer.CustomerSearch.updateCustomizeSearch')
          this.modifystatus = true
          this.CustomizeId = item._id
          this.formdata.kName = item.kName
          this.formdata.menu = item.menu
          this.showCache(item)
        }
        vm.unwatch = vm.$watch(function () {
          return vm.formdata.menu
        }, function (newval, oldval) {
          if (newval !== this.propsitem.menu || this.isEmptyObject(this.propsitem)) {
            vm.chooseOptions = []
            vm.formdata.query = {}
            let choose = deepClone(vm.searchOptions)[0]
            vm.chooseOptions.push(choose)
            Vue.set(vm.formdata.query, choose.value, '')
          } else {
            this.showCache(this.propsitem)
          }
        }, {deep: true})
      },
      addOptions () {
        if (this.notChooseOptions.length <= 0) {
          this.$message.error(this.$t('customer.CustomerSearch.noChooseTips'))
          return
        }
        let item = deepClone(this.notChooseOptions[0])
        if (item.inputType === 'checkbox') {
          Vue.set(this.formdata.query, item.value, [])
        } else if (item.inputType === 'date' || item.inputType === 'time' || item.inputType === 'datetime') {
          if (!this.formdata.query[item.value]) {
            Vue.set(this.formdata.query, item.value, {})
          }
          if (!this.formdata.query[item.value][item.timeindex]) {
            Vue.set(this.formdata.query[item.value], item.timeindex, {})
            Vue.set(this.formdata.query[item.value][item.timeindex], 'relate', 'JGx0')
            Vue.set(this.formdata.query[item.value][item.timeindex], 'value', '')
          }
        } else {
          Vue.set(this.formdata.query, item.value, '')
        }
        if (item.inputType === 'area') {
          Vue.set(this.formdata.query, 'city', '')
        }
        this.chooseOptions.push(item)
      },
      deleteOptions (option, index) {
        let vm = this
        if (option.inputType === 'time' || option.inputType === 'date' || option.inputType === 'datetime') {
          Vue.delete(vm.formdata.query[option.value], option.timeindex)
          if (this.isEmptyObject(this.formdata.query[option.value])) {
            Vue.delete(this.formdata.query, option.value)
          }
        } else {
          Vue.delete(vm.formdata.query, option.value)
        }
        if (option.inputType === 'area') {
          Vue.delete(vm.formdata.query, 'city')
        }
        vm.chooseOptions.splice(index, 1)
      },
      labelChange (name, index) {
        let array = deepClone(this.searchOptions)
        let label = this.chooseOptions[index].label
        let timeForeach = false
        array.forEach((item) => {
          if (item.label === label) {
            if (item.inputType === 'time' || item.inputType === 'date' || item.inputType === 'datetime') {
              let timeindexCache = this.chooseOptions[index].timeindex
              if (item.timeindex === timeindexCache) {
                Vue.delete(this.formdata.query[item.value], timeindexCache)
                if (this.isEmptyObject(this.formdata.query[item.value])) {
                  Vue.delete(this.formdata.query, item.value)
                }
              }
            } else {
              Vue.delete(this.formdata.query, item.value)
            }
            if (item.inputType === 'area') {
              Vue.delete(this.formdata.query, 'city')
            }
          }
        })
        array.forEach((item) => {
          if (item.value === name) {
            if (item.inputType === 'area') {
              Vue.set(this.formdata.query, 'city', '')
              this.chooseOptions.splice(index, 1, item)
            }
            if (item.inputType === 'checkbox') {
              Vue.set(this.formdata.query, item.value, [])
              this.chooseOptions.splice(index, 1, item)
            } else if (item.inputType === 'date' || item.inputType === 'time' || item.inputType === 'datetime') {
              if (!this.formdata.query[item.value]) {
                Vue.set(this.formdata.query, item.value, {})
              }
              if (!this.formdata.query[item.value][item.timeindex] && !timeForeach) {
                Vue.set(this.formdata.query[item.value], item.timeindex, {})
                Vue.set(this.formdata.query[item.value][item.timeindex], 'relate', 'JGx0')
                Vue.set(this.formdata.query[item.value][item.timeindex], 'value', '')
                this.chooseOptions.splice(index, 1, item)
                timeForeach = true
              }
            } else {
              Vue.set(this.formdata.query, item.value, '')
              this.chooseOptions.splice(index, 1, item)
            }
          }
        })
      },
      saveSearch () {
        let payload = this.formdata.query
        let data = {
          kName: this.formdata.kName,
          menu: this.formdata.menu,
          query: {}
        }
        if (!data.kName) {
          this.$message.error(this.$t('customer.CustomerSearch.pleaseEnterSearchName'))
          return
        }
        for (let key in payload) {
          let value = payload[key]
          if (value !== '') {
            if (value instanceof Object && !(value instanceof Array)) {
              if (!this.isEmptyObject(value)) {
                let timekeys = Object.keys(value)
                if (timekeys.length === 1) {
                  if (value[timekeys[0]].value) {
                    let timekey = value[timekeys[0]].relate
                    let timevalue = value[timekeys[0]].value ? getFormatDateTime(value[timekeys[0]].value) : ''
                    let timedata = {}
                    timedata[timekey] = timevalue
                    data.query[key] = timedata
                  }
                } else if (timekeys.length === 2) {
                  let timekey1 = value[timekeys[0]].relate
                  let timekey2 = value[timekeys[1]].relate
                  if (timekey1 === timekey2) {
                    this.$message.error(this.$t('customer.CustomerSearch.timeFormatErrorTip'))
                    return
                  }
                  if (value[timekeys[0]].value || value[timekeys[1]].value) {
                    let timedata = {}
                    if (value[timekeys[0]].value) {
                      timedata[timekey1] = value[timekeys[0]].value
                    }
                    if (value[timekeys[1]].value) {
                      timedata[timekey2] = value[timekeys[1]].value
                    }
                    data.query[key] = timedata
                  }
                }
              }
            } else {
              data.query[key] = value
            }
          }
        }
        let updatetype = this.modifystatus ? 'updateCustomerQuickSearch' : 'addCustomerQuickSearch'
        if (this.modifystatus) {
          data.kId = this.CustomizeId
        }
        this.$store.dispatch(updatetype, data).then((data) => {
          let vm = this
          if (data) {
            vm.reset()
            vm.dialogModel = false
          }
        })
      },
      cancel () {
        this.reset()
        this.dialogModel = false
      },
      reset () {
        this.title = ''
        this.propsitem = {}
        this.modifystatus = false
        this.chooseOptions = []
        this.formdata = {
          menu: 'customer_my',
          kName: '',
          query: {}
        }
        let choose = deepClone(this.searchOptions)[0]
        this.chooseOptions.push(choose)
        Vue.set(this.formdata.query, choose.value, '')
      },
      handleClose () {
        this.reset()
        this.unwatch()
      },
      selectOptions (item) {
        return this.notChooseOptions.push(item)
      }
    },
    computed: {
      notChooseOptions () {
        let vm = this
        let notChoose = []
        let notChooseValue = []
        let values = []
        let search = vm.searchOptions
        vm.chooseOptions.forEach((item) => {
          values.push(item.value)
        })
        search.forEach((item) => {
          if (values.indexOf(item.value) === -1 && notChooseValue.indexOf(item.value) === -1) {
            notChoose.push(item)
            notChooseValue.push(item.value)
          } else if (values.indexOf(item.value) !== -1 && item.inputType === 'time' && vm.formdata.query[item.value] && !vm.formdata.query[item.value][item.timeindex]) {
            notChoose.push(item)
            notChooseValue.push(item.value)
          } else if (values.indexOf(item.value) !== -1 && item.inputType === 'date' && vm.formdata.query[item.value] && !vm.formdata.query[item.value][item.timeindex]) {
            notChoose.push(item)
            notChooseValue.push(item.value)
          } else if (values.indexOf(item.value) !== -1 && item.inputType === 'datetime' && vm.formdata.query[item.value] && !vm.formdata.query[item.value][item.timeindex]) {
            notChoose.push(item)
            notChooseValue.push(item.value)
          }
        })
        return notChoose
      },
      cities () {
        let cities = []
        if (this.formdata.query.province) {
          for (let i = 0; i < this.provinceCache.options.length; i++) {
            if (this.provinceCache.options[i].key === this.formdata.query.province) {
              cities = this.provinceCache.options[i].options
              break
            }
          }
        }
        return [{label: this.$t('public.all'), value: ''}, ...cities.map(city => ({label: city.name, value: city.key}))]
      }
    },
    beforeMount () {
      let p1 = this.$store.dispatch('getCache', {
        type: 'options',
        id: 'd7b9c68a-b50f-21d1-d5fd-41ea93f5f49c'
      })
      let p2 = this.$store.dispatch('getCache', {
        type: 'custTmpls'
      })
      let p3 = this.$store.dispatch('getCache', {
        type: 'custCategorys'
      })
      let p = Promise.all([p1, p2, p3])
      p.then(([provinceCache, custTmpls, custCategorysCache]) => {
        this.provinceCache = provinceCache
        let provinces = [{
          label: this.$t('public.all'),
          value: ''
        }, ...provinceCache.options.map(province => ({label: province.name, value: `${province.key}`}))]
        this.provinces = provinces
        let custTmpl = custTmpls[0]
        let statuses = [{label: this.$t('public.all'), value: ''}]
        for (let key in custTmpl.status) {
          statuses.push({label: custTmpl.status[key], value: key})
        }
        let sources = [{label: this.$t('public.all'), value: ''}, ...custTmpl.source.map(source => ({
          label: source.name,
          value: source.key
        }))]
        let custCategorys = [{
          label: this.$t('public.all'),
          value: ''
        }, ...custCategorysCache.map(category => ({
          label: category.cName,
          value: category._id
        }))]

        let localedOptions = [
          {label: this.$t('customer.categorySource'), value: 'categoryId', inputType: 'select', data: custCategorys},
          {label: this.$t('customer.custStatus'), value: 'status', inputType: 'select', data: statuses},
          {label: this.$t('customer.customerName'), value: 'name', inputType: 'input'},
          {label: this.$t('customer.custCall'), value: 'phone', inputType: 'input', validateType: 'Phone'},
          {label: this.$t('customer.dataSource'), value: 'custsource1', inputType: 'select', data: sources},
          {
            label: this.$t('customer.province'),
            value: 'province',
            inputType: 'area'
          },
          {label: this.$t('customer.updateTime'), value: 'lastUpdateTime', inputType: 'time', timeindex: 1},
          {label: this.$t('customer.updateTime'), value: 'lastUpdateTime', inputType: 'time', timeindex: 2},
          {label: this.$t('customer.createTime'), value: 'createTime', inputType: 'time', timeindex: 1},
          {label: this.$t('customer.createTime'), value: 'createTime', inputType: 'time', timeindex: 2},
          {label: this.$t('customer.contactPlan.contactPlanTime'), value: 'notifyTime', inputType: 'time', timeindex: 1},
          {label: this.$t('customer.contactPlan.contactPlanTime'), value: 'notifyTime', inputType: 'time', timeindex: 2},
          {label: this.$t('customer.importBatch'), value: 'batchNo', inputType: 'input'}
        ]

        let isFieldAdded = (fieldName) => fieldName === 'province' || fieldName === 'city' || fieldName === 'name' || fieldName === 'phone'
        custTmpl.stable_fields.forEach(stableField => {
          if (stableField.search && !isFieldAdded(stableField.name)) {
            localedOptions.push({label: stableField.value, value: stableField.name, inputType: 'input'})
          }
        })

        let customOptions = []
        let sortedCustomFields = sortCustomFields(custTmpl.custom_fields)
        sortedCustomFields.forEach(customField => {
          let option = {label: customField.name, value: customField._id}
          if (customField.type === 'single') {
            option.inputType = 'input'
          } else if (customField.type === 'multi') {
            option.inputType = 'textarea'
          } else if (customField.type === 'number') {
            option.inputType = 'input'
            option.validateType = 'Number'
          } else if (customField.type === 'dropdown') {
            if (customField.dic) {
              option.inputType = 'cascade'
              option.data = customField.dic
            } else {
              option.inputType = 'select'
              option.data = []
              for (let key in customField.choices) {
                let label = customField.choices[key] || ' '
                option.data.push({label, value: key})
              }
            }
          } else if (customField.type === 'checkbox' || customField.type === 'radio') {
            option.inputType = customField.type
            option.data = []
            for (let key in customField.choices) {
              option.data.push({label: customField.choices[key], value: key})
            }
          } else {
            option.inputType = customField.type
          }
          if (customField.value === 'email') {
            option.validateType = 'Email'
          }
          if (option.inputType === 'date' || option.inputType === 'datetime') {
            option.timeindex = 2
            let option1 = {label: option.label, value: option.value, inputType: option.inputType, timeindex: 1}
            customOptions.push(option1)
          }
          customOptions.push(option)
        })
        this.searchOptions = localedOptions.concat(customOptions)
        let choose = deepClone(this.searchOptions)[0]
        this.chooseOptions.push(choose)
        Vue.set(this.formdata.query, choose.value, '')
      })
    }
  }
</script>

<style lang="stylus" rel="stylesheet/stylus" scoped>
  @import "../../../assets/common.styl"
  .customizeSearch
    margin 0 0 0 30px
    .dialogbody
      padding-top 10px
      max-height: 560px;
      overflow auto
      .colorred
        color $c-pink
      .colorgreen
        color $c-main
    .footer
      text-align center
      margin 10px 10px
      .button
        background: $c-main;
        width 64px
        padding 0
        border none
        height 28px
        font-size 12px
        margin-bottom 10px
      /*.cancelbutton
        background-color $c-sub*/
    .formbody
      padding-left 70px
    .el-input
      width auto
    .formcontent
      padding-left 40px
    .relative
      width 100px
      margin 0 5px
    .width196
      width 196px
      display inline-block
    .formitem
      margin 5px 0
    .cursorpointer
      cursor pointer
</style>
